/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package thoughtworks;

import java.util.HashMap;
import java.util.Stack;

/**
 *
 * @author azouz
 */
public class RomanCalculator {

    public boolean isValidRomanNumber(String romanNubmer) {
        String romanNumberValidator = "^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$";
        return romanNubmer.matches(romanNumberValidator);
    }

    public int romanToArabic(String romanNumber) {
        int decimal = 0;
        int lastNumber = 0;
        String romanNumeral = romanNumber.toUpperCase();
        for (int x = romanNumeral.length() - 1; x >= 0; x--) {
            char convertToDecimal = romanNumeral.charAt(x);

            switch (convertToDecimal) {
                case 'M':
                    decimal = processDecimal(1000, lastNumber, decimal);
                    lastNumber = 1000;
                    break;

                case 'D':
                    decimal = processDecimal(500, lastNumber, decimal);
                    lastNumber = 500;
                    break;

                case 'C':
                    decimal = processDecimal(100, lastNumber, decimal);
                    lastNumber = 100;
                    break;

                case 'L':
                    decimal = processDecimal(50, lastNumber, decimal);
                    lastNumber = 50;
                    break;

                case 'X':
                    decimal = processDecimal(10, lastNumber, decimal);
                    lastNumber = 10;
                    break;

                case 'V':
                    decimal = processDecimal(5, lastNumber, decimal);
                    lastNumber = 5;
                    break;

                case 'I':
                    decimal = processDecimal(1, lastNumber, decimal);
                    lastNumber = 1;
                    break;
            }
        }
        return decimal;
    }

    private int processDecimal(int decimal, int lastNumber, int lastDecimal) {
        if (lastNumber > decimal) {
            return lastDecimal - decimal;
        } else {
            return lastDecimal + decimal;
        }
    }

    private HashMap<String, String> constantAssignments;
    private HashMap<String, String> computedLiterals;

    public RomanCalculator() {
        this.constantAssignments = new HashMap<String, String>();
        this.computedLiterals = new HashMap<String, String>();
    }

    private void HandleIsAssign(String line) {
        String[] splited = line.trim().split("\\s+");
        try {
            constantAssignments.put(splited[0], splited[2]);
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }

    private void handleCredet(String line) {
        try {
            String formatted = line.replaceAll("(is\\s+)|([c|C]redits\\s*)", "").trim();
            String[] keys = formatted.split("\\s");
            String toBeComputed = keys[keys.length - 2];
            float value = Float.parseFloat(keys[keys.length - 1]);
            String roman = "";

            for (int i = 0; i < keys.length - 2; i++) {
                roman += constantAssignments.get(keys[i]);
            }

            int romanNumber = this.romanToArabic(roman);
            float credit = (float) (value / romanNumber);
            computedLiterals.put(toBeComputed, credit + "");

        } catch (Exception e) {

        }
    }

    private void handleMuch(String line) {
        try {
            String formatted = line.split("\\sis\\s")[1].trim();
            formatted = formatted.replace("?", "").trim();
            String keys[] = formatted.split("\\s+");
            String romanResult = "";
            String completeResult = null;
            boolean errorOccured = false;

            for (String key : keys) {
                String romanValue = constantAssignments.get(key);
                if (romanValue == null) {
                    errorOccured = true;
                    break;
                }
                romanResult += romanValue;
            }

            if (!errorOccured) {
                romanResult = String.valueOf(this.romanToArabic(romanResult));
                completeResult = formatted + " is " + romanResult;
            }

            System.out.println(completeResult);

        } catch (Exception e) {

        }
    }

    private void handleMany(String line) {

        try {
            //Remove the unwanted words like "is" and "?"
            String formatted = line.split("(\\sis\\s)")[1];

            formatted = formatted.replace("?", "").trim();

            // search for all numerals for their values to compute the result
            String[] keys = formatted.split("\\s");

            boolean found = false;
            String roman = "";
            String outputResult = null;
            Stack<Float> cvalues = new Stack<Float>();

            for (String key : keys) {
                found = false;

                String romanValue = constantAssignments.get(key);
                if (romanValue != null) {
                    roman += romanValue;
                    found = true;
                }

                String computedValue = computedLiterals.get(key);
                if (!found && computedValue != null) {
                    cvalues.push(Float.parseFloat(computedValue));
                    found = true;
                }

                if (!found) {
                    System.out.println("NO IDEA");
                    break;
                }
            }

            if (found) {
                float res = 1;
                System.out.println(cvalues);
                for (int i = 0; i < cvalues.size(); i++) {
                    res *= cvalues.get(i);
                }

                int finalres = (int) res;
                if (roman.length() > 0) {
                    finalres = (int) (this.romanToArabic(roman) * res);
                }
                outputResult = formatted + " is " + finalres + " Credits";
            }

            System.out.println(outputResult);
        } catch (Exception e) {
        }

    }

    /**
     * Create project with Maven - create pojos and enums - create handlers
     *
     *
     * Main Class will have InputReaderParser have to extract new values
     *
     * InputReaderParser will have RomanCalculator
     *
     * RomanCalculator will check and calculate the Roman to Arabic numeral
     *
     *
     * OutputGenrator will genrate the ouput based on input
     *
     * Exception Handling and Messagin
     *
     * Parse each line of input Calculate based on this input Display the output
     * exceptions handling Assumtions .. i should write assumptions
     *
     */
    public static void main(String args[]) {
        RomanCalculator calculator = new RomanCalculator();
        calculator.HandleIsAssign("glob is I");
        calculator.HandleIsAssign("prok is V");
        calculator.HandleIsAssign("pish is X");
        calculator.HandleIsAssign("tegj is L");
        calculator.handleCredet("glob glob Silver is 34 Credits");
        calculator.handleCredet("glob prok Gold is 57800 Credits");
        calculator.handleCredet("pish pish Iron is 3910 Credits");
        System.out.println(4 * 17 + "aaa");
        calculator.handleMany("how many Credits is glob prok Silver ?");
        System.out.println(calculator.constantAssignments);
        System.out.println(calculator.computedLiterals);

    }

}
